# -*- coding: utf-8 -*-
# @file    : _types
# @Date    : 2020/11/26
# @Author  :
# @Version : 1.0.0
"""
Custom Types Define
"""
from typing import Mapping, Iterable


def free_hash(arg):
    try:
        return hash(arg)
    except Exception:
        if isinstance(arg, Mapping):
            return hash(frozendict(arg))
        elif isinstance(arg, Iterable):
            return hash(frozenset(free_hash(item) for item in arg))
        else:
            return id(arg)


class frozendict(dict):
    """
    冻结字典
    初始化后不允许修改
    """

    def __delitem__(self, key):
        raise NotImplementedError("'__delitem__' not supported on frozendict")

    def __setitem__(self, key, val):
        raise NotImplementedError("'__setitem__' not supported on frozendict")

    def clear(self):
        raise NotImplementedError("'clear' not supported on frozendict")

    def pop(self, key, default=None):
        raise NotImplementedError("'pop' not supported on frozendict")

    def popitem(self):
        raise NotImplementedError("'popitem' not supported on frozendict")

    def setdefault(self, key, default=None):
        raise NotImplementedError("'setdefault' not supported on frozendict")

    def update(self, *args, **kwargs):
        raise NotImplementedError("'update' not supported on frozendict")

    def __hash__(self):
        return hash(frozenset((key, free_hash(val)) for key, val in self.items()))


class sectiondict(frozendict):
    def __getitem__(self, key):
        if key in self:
            return super(sectiondict, self).__getitem__(key)
        return None


class configdict(frozendict):
    def __getitem__(self, key):
        if key in self:
            return super(configdict, self).__getitem__(key)
        return sectiondict()
